<script lang="ts">
	import RectButton from '$lib/components/Basic/Button/RectButton.svelte';

	// 定义组件Props接口
	interface InputProps {
		type?: 'text' | 'password' | 'email' | 'number' | 'tel' | 'url';
		value?: any;
		width?: string;
		placeholder?: string;
		disabled?: boolean;
		readonly?: boolean;
		required?: boolean;
		maxlength?: number;
		minlength?: number;
		size?: 'sm' | 'md' | 'lg';
		autocomplete?: 'on' | 'off' | string; // 使用更兼容的类型
		name?: string;
		id?: string;
		className?: string;
		error?: string;
		variant?: 'default' | 'filled' | 'outlined';
		clearable?: boolean;
		inputRef?: HTMLInputElement | null;
		onInput?: (value: any) => void;
		onClear?: () => void;
		onChange?: (value: any) => void;
		onKeydown?: (event: KeyboardEvent) => void;
	}

	// 使用$props获取组件属性
	let {
		type = 'text',
		value = $bindable(),
		width = '100%',
		placeholder = '',
		disabled = false,
		readonly = false,
		required = false,
		maxlength,
		minlength,
		size = 'md',
		autocomplete,
		name,
		id,
		className,
		error,
		variant = 'default',
		clearable = false,
		inputRef = $bindable(null),
		onInput,
		onClear,
		onChange,
		onKeydown
	}: InputProps = $props();

	// 内部状态
	let isFocused = $state(false);
	let isFilled = $state(false);

	// 处理聚焦状态
	const handleFocus = () => {
		isFocused = true;
	};

	// 处理失焦状态
	const handleBlur = () => {
		isFocused = false;
	};

	// 监听value变化，判断是否填充
	$effect(() => {
		if (value !== undefined && value !== null && value !== '' && value.length > 0) {
			isFilled = true;
		} else {
			isFilled = false;
		}
	});

	// 转发事件
	function handleChange() {
		onChange?.(value);
	}

	// 处理清除按钮点击事件
	function handleClear() {
		value = '';
		onClear?.();
	}
	// 处理输入事件
	function handleInput() {
		onInput?.(value);
	}
	// 处理键盘事件
	function handleKeydown(event: KeyboardEvent) {
		onKeydown?.(event);
	}
</script>

<div
	class={`input-container ${variant} ${isFocused ? 'focused' : ''} ${isFilled ? 'filled' : ''} ${disabled ? 'disabled' : ''} ${error ? 'error' : ''} ${className || ''}`}
	class:clearable
	class:small={size === 'sm'}
	class:medium={size === 'md'}
	class:large={size === 'lg'}
	aria-disabled={disabled}
	aria-invalid={!!error}
	style:--width={width}
>
	<input
		bind:this={inputRef}
		bind:value
		{type}
		{disabled}
		{readonly}
		{required}
		{maxlength}
		{minlength}
		autocomplete={autocomplete as any}
		{name}
		{id}
		onfocus={handleFocus}
		onblur={handleBlur}
		onchange={handleChange}
		oninput={handleInput}
		onkeydown={handleKeydown}
		class="input-field"
	/>
	{#if placeholder}
		<label
			class={`input-label ${isFocused || isFilled ? 'active' : ''}`}
			for={id}
			aria-hidden={!placeholder}
		>
			{placeholder}
		</label>
	{/if}
	{#if clearable && value}
		<div class="clear-button">
			<RectButton icon="symbol/close" variant="info" type="link" {size} onclick={handleClear}
			></RectButton>
		</div>
	{/if}
	{#if error}
		<div class="input-error" role="alert">
			{error}
		</div>
	{/if}
</div>

<style lang="scss">
	.small {
		font-size: 12px;
		line-height: 14px;
		height: 26px;
		// 当聚焦或有内容时，提示文字缩小至左上角
		&.clearable .input-field {
			padding-right: 27px;
		}
	}
	.medium {
		font-size: 13px;
		line-height: 15px;
		height: 28px;
		&.clearable .input-field {
			padding-right: 31px;
		}
	}
	.large {
		font-size: 14px;
		line-height: 16px;
		height: 32px;
		&.clearable .input-field {
			padding-right: 35px;
		}
	}

	.input-container {
		position: relative;
		display: inline-block;
		width: var(--width);
		background-color: var(--color-page);

		&.focused .input-field {
			// 聚焦时光标颜色跟随主色
			border-color: var(--color-primary-500);
			caret-color: var(--color-primary-500);
		}
		&.focused .input-label {
			color: var(--color-primary-600);
		}
		&:hover:not(.focused) .input-field {
			border-color: var(--color-info-400);
		}

		&.disabled {
			opacity: 0.6;
			cursor: not-allowed;

			.input-field {
				background-color: var(--bg-disabled);
				cursor: not-allowed;
			}

			.input-label {
				cursor: not-allowed;
			}
		}

		&.error {
			.input-field {
				border-color: var(--color-error-500);
			}
		}
	}

	.input-field {
		position: relative;
		width: 100%;
		height: 100%;
		padding: 0 11px;
		font-size: inherit;
		line-height: inherit;
		color: var(--color-info-700);
		background-color: transparent;
		border: 1px solid var(--color-info-300);
		border-radius: 6px;
		outline: none;
		box-sizing: border-box;

		&:disabled {
			background-color: var(--bg-disabled);
			cursor: not-allowed;
		}
	}

	.input-label {
		position: absolute;
		left: 11px;
		top: 50%;
		transform: translateY(-50%);
		color: var(--color-info-500);
		pointer-events: none;
		transition:
			top 0.2s,
			left 0.2s,
			scale 0.2s;
		background-color: var(--color-page);
		padding: 0 4px;
		z-index: 1;
		will-change: transform;
		user-select: none;
		&.active {
			top: -3px;
			left: 0;
			scale: 0.75;
		}
	}

	.input-error {
		position: absolute;
		top: 100%;
		left: 0;
		margin-top: 4px;
		font-size: 12px;
		color: var(--color-error-500);
		padding: 2px 0;
	}
	.clear-button {
		position: absolute;
		top: 50%;
		right: 0px;
		transform: translateY(-50%);
	}
</style>
